import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'package:date_format/date_format.dart';
import 'package:dotted_border/dotted_border.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:get/get_connect/http/src/utils/utils.dart';
import 'package:shen_nai/app/user_controller.dart';
import 'package:shen_nai/entity/data_entity.dart';
import 'package:shen_nai/entity/data_list_entity.dart';
import 'package:shen_nai/entity/device_entity.dart';
import 'package:shen_nai/eventbus/event_bus.dart';
import 'package:shen_nai/routes/app_routes.dart';
import 'package:shen_nai/socket/data_utils.dart';
import 'package:shen_nai/socket/socket_server_manage.dart';

//图表详情页
class LineChartDetailPage extends StatefulWidget {
  const LineChartDetailPage({Key? key}) : super(key: key);

  @override
  State<LineChartDetailPage> createState() => _LineChartDetailPageState();
}

class _LineChartDetailPageState extends State<LineChartDetailPage> {
  //设备数据
  DeviceEntity? _deviceEntity;
  //监听数据回调
  StreamSubscription? _subscription;
  //曲线位置
  int _selectFirstItem = 0;
  int _selectSecondItem = 1;
  int _selectThirdItem = 0;
  int _selectFourItem = 1;
  //曲线的名字
  String _firstName = '';
  String _secondName = '';
  String _thirdName = '';
  String _fourName = '';
  //曲线当前值
  String _firstValue = '0';
  String _secondValue = '0';
  String _thirdValue = '0';
  String _fourValue = '0';
  //实时模拟量数据
  List<Map> dataMap = [];
  //实时开关量数据
  List<Map> switchDataMap = [];
  List<DataEntity> dataEntityList = [];

  //一屏幕多少个点
  double _dotNum = 1000;
  //曲线的数据列表
  List<DataListEntity> _firstItemList = [];
  List<DataListEntity> _secondItemList = [];
  List<DataListEntity> _thridItemList = [];
  List<DataListEntity> _fourItemList = [];

  //有效字段集合
  List<String> _effectiveList = [];
  //开关的有效字段
  List<String> _switchEffectiveList = [];

  //30分钟或历史数据模拟量
  List<Map> dataHistoryMap = [];
  //30分钟或历史数据开关量
  List<Map> dataSwitchHistoryMap = [];
  List<DataEntity> dataHistoryEntityList = [];
  //总共30分钟或历史数据模拟量
  List<Map> totalDataHistoryMap = [];
  //总共30分钟或历史数据开关量
  List<Map> totalDataSwitchHistoryMap = [];
  //滚动监听
  late ScrollController _scrollController;
  //图表的宽度
  double lineChartWidth = 0;
  //是否在加载最新历史数据
  bool isLoadHistory = false;
  //一次加载数据量
  int loadHistoryLength = 9000;
  //是否还有历史数据
  bool isMoreHistory = true;
  //当前时间
  DateTime dateTime = DateTime.now();
  //第一次加载历史数据
  bool isFirstLoadHistroy = true;

  @override
  void initState() {
    super.initState();
    // 强制横屏
    SystemChrome.setPreferredOrientations(
        [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
    _deviceEntity = Get.arguments;

    _scrollController = ScrollController();

    _scrollController.addListener(() {
      //log(_scrollController.position.)
      //log(_scrollController.offset.toString());
      if (_deviceEntity!.itemType == 2) {
        //历史曲线
        if (!isLoadHistory && isMoreHistory && _scrollController.offset <= 0) {
          isLoadHistory = true;
          // dateTime =
          //     dateTime.subtract(Duration(seconds: 10 * loadHistoryLength));
          queryHistoryData(
              'query historymb ${getNowFormatTime(dateTime)} 1 ${_deviceEntity!.number} $loadHistoryLength');
        }
      }
    });

    _effectiveList = Get.find<UserController>()
        .bit100List
        .where((element) => element != 'NULL')
        .toList();

    _switchEffectiveList = Get.find<UserController>()
        .bit140List
        .where((element) => element != 'NULL')
        .toList();

    if (_deviceEntity!.itemType == 0) {
      _dotNum = 600;
    } else {
      _dotNum = 1800;
    }

    if (_deviceEntity!.itemType == 1) {
      queryHistoryData("query q30mb ${_deviceEntity!.number}");
    } else if (_deviceEntity!.itemType == 2) {
      queryHistoryData(
          'query historymb ${getNowFormatTime(dateTime)} 1 ${_deviceEntity!.number} $loadHistoryLength');
    }

    _subscription = eventBus.on<EquipmentInformationEvent>().listen((event) {
      //log(event.data.serialNumber!);
      if (_deviceEntity!.number == event.data.serialNumber!) {
        List<int> list = [];
        list.addAll(event.data.bit14List!);
        list.addAll(event.data.bit7List!);
        Map map = {};
        Map switchMap = {};
        for (var i = 0; i < Get.find<UserController>().bit100List.length; i++) {
          if (Get.find<UserController>().bit100List[i] != 'NULL') {
            map[Get.find<UserController>().bit100List[i]] = list[i];
          }
        }
        for (var i = 0; i < Get.find<UserController>().bit140List.length; i++) {
          if (Get.find<UserController>().bit140List[i] != 'NULL') {
            switchMap[Get.find<UserController>().bit140List[i]] =
                event.data.switchList![i];
          }
        }
        setState(() {
          _firstName = map.keys.elementAt(_selectFirstItem);
          _firstValue = map.values.elementAt(_selectFirstItem).toString();
          _secondName = map.keys.elementAt(_selectSecondItem);
          _secondValue = map.values.elementAt(_selectSecondItem).toString();
          _thirdName = switchMap.keys.elementAt(_selectThirdItem);
          _thirdValue = switchMap.values.elementAt(_selectThirdItem).toString();
          _fourName = switchMap.keys.elementAt(_selectFourItem);
          _fourValue = switchMap.values.elementAt(_selectFourItem).toString();
        });
        DateTime dateTime = DateTime.now();
        event.data.dateTime = dateTime;
        dataMap.add(map);
        switchDataMap.add(switchMap);
        dataEntityList.add(event.data);
        //获取实时数据
        if (_deviceEntity!.itemType == 0) {
          processData();
        }
      }
    });
  }

  //处理实时数据
  void processData() {
    if ((dataMap.length - 1) % _dotNum == 0) {
      if (dataMap.length - 1 != 0) {
        _firstItemList.last.flList.add(FlSpot(
            (dataMap.length - 1) % (_dotNum + 1),
            double.parse(
                dataMap.last.values.elementAt(_selectFirstItem).toString())));

        _firstItemList.last.dataList.add(dataEntityList.last);
        _secondItemList.last.flList.add(FlSpot(
            (dataMap.length - 1) % (_dotNum + 1),
            double.parse(
                dataMap.last.values.elementAt(_selectSecondItem).toString())));
        _secondItemList.last.dataList.add(dataEntityList.last);
        _thridItemList.last.flList.add(FlSpot(
            (switchDataMap.length - 1) % (_dotNum + 1),
            double.parse(switchDataMap.last.values
                .elementAt(_selectThirdItem)
                .toString())));
        _thridItemList.last.dataList.add(dataEntityList.last);
        _fourItemList.last.flList.add(FlSpot(
            (switchDataMap.length - 1) % (_dotNum + 1),
            double.parse(switchDataMap.last.values
                .elementAt(_selectFourItem)
                .toString())));
        _fourItemList.last.dataList.add(dataEntityList.last);
      }
      _firstItemList.add(DataListEntity([], []));
      _secondItemList.add(DataListEntity([], []));
      _thridItemList.add(DataListEntity([], []));
      _fourItemList.add(DataListEntity([], []));
    }

    setState(() {
      _firstItemList.last.flList.add(FlSpot(
          (dataMap.length - 1) % _dotNum,
          double.parse(
              dataMap.last.values.elementAt(_selectFirstItem).toString())));
      _firstItemList.last.dataList.add(dataEntityList.last);
      _secondItemList.last.flList.add(FlSpot(
          (dataMap.length - 1) % _dotNum,
          double.parse(
              dataMap.last.values.elementAt(_selectSecondItem).toString())));
      _secondItemList.last.dataList.add(dataEntityList.last);
      _thridItemList.last.flList.add(FlSpot(
          (switchDataMap.length - 1) % _dotNum,
          double.parse(switchDataMap.last.values
              .elementAt(_selectThirdItem)
              .toString())));
      _thridItemList.last.dataList.add(dataEntityList.last);
      _fourItemList.last.flList.add(FlSpot(
          (switchDataMap.length - 1) % _dotNum,
          double.parse(switchDataMap.last.values
              .elementAt(_selectFourItem)
              .toString())));
      _fourItemList.last.dataList.add(dataEntityList.last);
    });
    if ((dataMap.length - 1) >= _dotNum) {
      _scrollController
          .jumpTo((dataMap.length - 1 - _dotNum) * lineChartWidth / _dotNum);
    }
  }

  @override
  void dispose() {
    // 强制竖屏
    // SystemChrome.setPreferredOrientations(
    //     [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
    _subscription?.cancel();
    _scrollController.dispose();
    //Get.back();
    super.dispose();
  }
  //界面绘制
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        centerTitle: false,
        titleSpacing: 0,
        title: Text(
          _deviceEntity!.name ?? '',
          maxLines: 1,
          overflow: TextOverflow.ellipsis,
          style: const TextStyle(color: Colors.white, fontSize: 12),
        ),
        actions: [
          Row(
            children: [
              const Text(
                '质保金：',
                style: TextStyle(color: Colors.white, fontSize: 12),
              ),
              Text(
                _deviceEntity!.qualityIsBuy == 0 ? '未付' : '已付',
                style: TextStyle(
                    color: _deviceEntity!.qualityIsBuy == 0
                        ? Colors.red
                        : Colors.green,
                    fontSize: 12),
              ),
              const SizedBox(
                width: 10,
              ),
              const Text(
                '质保期：',
                style: TextStyle(color: Colors.white, fontSize: 12),
              ),
              Text(
                _deviceEntity!.qualityIsBuy == 0
                    ? '${_deviceEntity!.qualityDays}天'
                    : '完成',
                style: TextStyle(
                    color: _deviceEntity!.qualityIsBuy == 0
                        ? Colors.red
                        : Colors.green,
                    fontSize: 12),
              ),
              SizedBox(
                width: Get.find<UserController>().jurisdiction == 0 ? 10 : 5,
              ),
              Get.find<UserController>().jurisdiction != 2
                  ? ElevatedButton(
                      onPressed: () {
                        Get.toNamed(AppRoute.REAL_DATA,
                            arguments: _deviceEntity);
                      },
                      child: const Text(
                        '实时数据',
                        style: TextStyle(fontSize: 12),
                      ),
                      style: ElevatedButton.styleFrom(
                          primary: const Color(0xff3486F7),
                          minimumSize: const Size(0, 0),
                          padding: const EdgeInsets.symmetric(
                              vertical: 4, horizontal: 8)),
                    )
                  : const SizedBox(),
              const SizedBox(
                width: 5,
              ),
              ElevatedButton(
                onPressed: () {
                  if (_deviceEntity!.itemType != 0) {
                    _deviceEntity!.itemType = 0;
                    _dotNum = 600;
                    fillDataList(_firstItemList, _selectFirstItem, dataMap,
                        dataEntityList);
                    fillDataList(_secondItemList, _selectSecondItem, dataMap,
                        dataEntityList);
                    fillDataList(_thridItemList, _selectThirdItem,
                        switchDataMap, dataEntityList);
                    fillDataList(_fourItemList, _selectFourItem, switchDataMap,
                        dataEntityList);
                  }
                },
                child: const Text(
                  '实时曲线',
                  style: TextStyle(fontSize: 12),
                ),
                style: ElevatedButton.styleFrom(
                    primary: _deviceEntity!.itemType == 0
                        ? const Color(0xff3486F7)
                        : const Color(0xffEE6D61),
                    minimumSize: const Size(0, 0),
                    padding:
                        const EdgeInsets.symmetric(vertical: 4, horizontal: 8)),
              ),
              const SizedBox(
                width: 5,
              ),
              ElevatedButton(
                onPressed: () {
                  if (_deviceEntity!.itemType != 1) {
                    _deviceEntity!.itemType = 1;
                    _dotNum = 1800;
                    isFirstLoadHistroy = true;
                    totalDataHistoryMap.clear();
                    totalDataSwitchHistoryMap.clear();
                    queryHistoryData("query q30mb ${_deviceEntity!.number}");
                  }
                },
                child: const Text('前90分钟', style: TextStyle(fontSize: 12)),
                style: ElevatedButton.styleFrom(
                    primary: _deviceEntity!.itemType == 1
                        ? const Color(0xff3486F7)
                        : const Color(0xffEE6D61),
                    minimumSize: const Size(0, 0),
                    padding:
                        const EdgeInsets.symmetric(vertical: 4, horizontal: 8)),
              ),
              const SizedBox(
                width: 5,
              ),
              ElevatedButton(
                onPressed: () {
                  if (_deviceEntity!.itemType != 2) {
                    _deviceEntity!.itemType = 2;
                    _dotNum = 1800;
                    dateTime = DateTime.now();
                    isFirstLoadHistroy = true;
                    isMoreHistory = true;
                    totalDataHistoryMap.clear();
                    totalDataSwitchHistoryMap.clear();

                    queryHistoryData(
                        'query historymb ${getNowFormatTime(dateTime)} 1 ${_deviceEntity!.number} $loadHistoryLength');
                  }
                },
                child: const Text('历史曲线', style: TextStyle(fontSize: 12)),
                style: ElevatedButton.styleFrom(
                    primary: _deviceEntity!.itemType == 2
                        ? const Color(0xff3486F7)
                        : const Color(0xffEE6D61),
                    minimumSize: const Size(0, 0),
                    padding:
                        const EdgeInsets.symmetric(vertical: 4, horizontal: 8)),
              ),
            ],
          )
        ],
      ),
      body: Container(
        margin: EdgeInsets.only(
            left: 15, right: MediaQuery.of(context).padding.right, bottom: 15),
        decoration: BoxDecoration(
          border: Border.all(color: Colors.white.withOpacity(.22)),
          borderRadius: BorderRadius.circular(2),
        ),
        child: Column(
          children: [
            SizedBox(
              height: 30,
              child: Row(
                children: [
                  Container(
                    width: 12,
                  ),
                  Text(
                    '$_firstName:$_firstValue',
                    style:
                        const TextStyle(color: Color(0xffEA8D48), fontSize: 12),
                  ),
                  const SizedBox(
                    width: 25,
                  ),
                  Text(
                    '$_secondName:$_secondValue',
                    style:
                        const TextStyle(color: Color(0xff4C93DD), fontSize: 12),
                  ),
                  const SizedBox(
                    width: 25,
                  ),
                  Text(
                    '$_thirdName:$_thirdValue',
                    style: const TextStyle(color: Colors.red, fontSize: 12),
                  ),
                  const SizedBox(
                    width: 25,
                  ),
                  Text(
                    '$_fourName:$_fourValue',
                    style:
                        const TextStyle(color: Color(0xffEA68A2), fontSize: 12),
                  ),
                ],
              ),
            ),
            Container(
              height: 1,
              color: const Color(0xffF3F3F3).withOpacity(.26),
            ),
            Expanded(
              child: Column(
                children: [
                  Expanded(
                      child: Row(
                    children: [
                      SizedBox(
                        width: 90,
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.end,
                          children: [
                            Expanded(
                              flex: 2,
                              child: InkWell(
                                onTap: () {
                                  _showDialog(0);
                                },
                                child: Row(
                                  mainAxisAlignment: MainAxisAlignment.end,
                                  children: [
                                    Container(
                                      width: 62,
                                      alignment: Alignment.centerRight,
                                      child: Text(
                                        _firstName,
                                        maxLines: 1,
                                        overflow: TextOverflow.ellipsis,
                                        style: const TextStyle(
                                            color: Colors.white, fontSize: 12),
                                      ),
                                    ),
                                    const SizedBox(
                                      width: 5,
                                    ),
                                    Image.asset(
                                      'assets/images/down.png',
                                      width: 8,
                                    ),
                                    const SizedBox(
                                      width: 5,
                                    ),
                                  ],
                                ),
                              ),
                            ),
                            Expanded(
                              flex: 2,
                              child: InkWell(
                                onTap: () {
                                  _showDialog(1);
                                },
                                child: Row(
                                  mainAxisAlignment: MainAxisAlignment.end,
                                  children: [
                                    Container(
                                      width: 62,
                                      alignment: Alignment.centerRight,
                                      child: Text(
                                        _secondName,
                                        maxLines: 1,
                                        overflow: TextOverflow.ellipsis,
                                        style: const TextStyle(
                                            color: Colors.white, fontSize: 12),
                                      ),
                                    ),
                                    const SizedBox(
                                      width: 5,
                                    ),
                                    Image.asset(
                                      'assets/images/down.png',
                                      width: 8,
                                    ),
                                    const SizedBox(
                                      width: 5,
                                    ),
                                  ],
                                ),
                              ),
                            ),
                            Expanded(
                              flex: 1,
                              child: InkWell(
                                onTap: () {
                                  _showDialog(2);
                                },
                                child: Row(
                                  mainAxisAlignment: MainAxisAlignment.end,
                                  children: [
                                    Container(
                                      width: 62,
                                      alignment: Alignment.centerRight,
                                      child: Text(
                                        _thirdName,
                                        maxLines: 1,
                                        overflow: TextOverflow.ellipsis,
                                        style: const TextStyle(
                                            color: Colors.white, fontSize: 12),
                                      ),
                                    ),
                                    const SizedBox(
                                      width: 5,
                                    ),
                                    Image.asset(
                                      'assets/images/down.png',
                                      width: 8,
                                    ),
                                    const SizedBox(
                                      width: 5,
                                    ),
                                  ],
                                ),
                              ),
                            ),
                            Expanded(
                              flex: 1,
                              child: InkWell(
                                onTap: () {
                                  _showDialog(3);
                                },
                                child: Row(
                                  mainAxisAlignment: MainAxisAlignment.end,
                                  children: [
                                    Container(
                                      width: 62,
                                      alignment: Alignment.centerRight,
                                      child: Text(
                                        _fourName,
                                        maxLines: 1,
                                        overflow: TextOverflow.ellipsis,
                                        style: const TextStyle(
                                            color: Colors.white, fontSize: 12),
                                      ),
                                    ),
                                    const SizedBox(
                                      width: 5,
                                    ),
                                    Image.asset(
                                      'assets/images/down.png',
                                      width: 8,
                                    ),
                                    const SizedBox(
                                      width: 5,
                                    ),
                                  ],
                                ),
                              ),
                            )
                          ],
                        ),
                      ),
                      Expanded(
                          child: LayoutBuilder(builder: (context, containers) {
                        return MediaQuery.removePadding(
                            removeRight: true,
                            removeLeft: true,
                            context: context,
                            child: Stack(
                              children: [
                                Positioned(
                                    width: containers.maxWidth,
                                    height: containers.maxHeight,
                                    child: DottedBorder(
                                      customPath: (size) {
                                        return getPath(size);
                                      },
                                      dashPattern: [
                                        containers.maxHeight,
                                        containers.maxHeight
                                      ],
                                      strokeWidth: 1,
                                      color: Colors.white.withOpacity(.12),
                                      padding: EdgeInsets.zero,
                                      child: const SizedBox(),
                                    )),
                                ListView.builder(
                                  physics: _deviceEntity!.itemType == 0
                                      ? const NeverScrollableScrollPhysics()
                                      : null,
                                  controller: _scrollController,
                                  scrollDirection: Axis.horizontal,
                                  itemBuilder: (context, position) {
                                    return Column(
                                      children: [
                                        Container(
                                          height: (containers.maxHeight) / 3,
                                          width: containers.maxWidth,
                                          decoration: BoxDecoration(
                                              border: Border(
                                                  bottom: BorderSide(
                                            color: const Color(0xffF3F3F3)
                                                .withOpacity(.26),
                                          ))),
                                          child: getLineChartView(
                                              _firstItemList,
                                              position,
                                              const Color(0xff4D96E2),
                                              _dotNum,
                                              0,
                                              10000,
                                              0,
                                              containers.maxWidth),
                                        ),
                                        Container(
                                          height: (containers.maxHeight) / 3,
                                          width: containers.maxWidth,
                                          decoration: BoxDecoration(
                                              border: Border(
                                                  bottom: BorderSide(
                                            color: const Color(0xffF3F3F3)
                                                .withOpacity(.26),
                                          ))),
                                          child: getLineChartView(
                                              _secondItemList,
                                              position,
                                              const Color(0xff00AF2D),
                                              _dotNum,
                                              0,
                                              10000,
                                              0,
                                              containers.maxWidth),
                                        ),
                                        Container(
                                          height: (containers.maxHeight) / 6,
                                          width: containers.maxWidth,
                                          decoration: BoxDecoration(
                                              border: Border(
                                                  bottom: BorderSide(
                                            color: const Color(0xffF3F3F3)
                                                .withOpacity(.26),
                                          ))),
                                          child: getLineChartView(
                                              _thridItemList,
                                              position,
                                              Colors.red,
                                              _dotNum,
                                              0,
                                              2,
                                              0,
                                              containers.maxWidth),
                                        ),
                                        Container(
                                          height: (containers.maxHeight) / 6,
                                          width: containers.maxWidth,
                                          decoration: BoxDecoration(
                                              border: Border(
                                                  bottom: BorderSide(
                                            color: const Color(0xffF3F3F3)
                                                .withOpacity(.26),
                                          ))),
                                          child: getLineChartView(
                                              _fourItemList,
                                              position,
                                              const Color(0xffEA68A2),
                                              _dotNum,
                                              0,
                                              2,
                                              0,
                                              containers.maxWidth),
                                        )
                                      ],
                                    );
                                  },
                                  itemCount: _firstItemList.length,
                                )
                              ],
                            ));
                      }))
                    ],
                  )),
                  Container(
                    margin: const EdgeInsets.only(left: 90),
                    child: getScaleLine(),
                  )
                ],
              ),
            )
          ],
        ),
      ),
    );
  }

  //绘制分割线
  Path getPath(Size size) {
    if (_dotNum == 600) {
      double part = size.width / 6;
      return Path()
        ..moveTo(0, 0)
        ..lineTo(0, size.height)
        ..moveTo(part, 0)
        ..lineTo(part, size.height)
        ..moveTo(part * 2, 0)
        ..lineTo(part * 2, size.height)
        ..moveTo(part * 3, 0)
        ..lineTo(part * 3, size.height)
        ..moveTo(part * 4, 0)
        ..lineTo(part * 4, size.height)
        ..moveTo(part * 5, 0)
        ..lineTo(part * 5, size.height)
        ..moveTo(part * 6, 0)
        ..lineTo(part * 6, size.height);
      // ..moveTo(0, size.height)
      // ..lineTo(size.width, size.height);
    } else {
      double part = size.width / 18;
      return Path()
        ..moveTo(0, 0)
        ..lineTo(0, size.height)
        ..moveTo(part, 0)
        ..lineTo(part, size.height)
        ..moveTo(part * 2, 0)
        ..lineTo(part * 2, size.height)
        ..moveTo(part * 3, 0)
        ..lineTo(part * 3, size.height)
        ..moveTo(part * 4, 0)
        ..lineTo(part * 4, size.height)
        ..moveTo(part * 5, 0)
        ..lineTo(part * 5, size.height)
        ..moveTo(part * 6, 0)
        ..lineTo(part * 6, size.height)
        ..moveTo(part * 7, 0)
        ..lineTo(part * 7, size.height)
        ..moveTo(part * 8, 0)
        ..lineTo(part * 8, size.height)
        ..moveTo(part * 9, 0)
        ..lineTo(part * 9, size.height)
        ..moveTo(part * 10, 0)
        ..lineTo(part * 10, size.height)
        ..moveTo(part * 11, 0)
        ..lineTo(part * 11, size.height)
        ..moveTo(part * 12, 0)
        ..lineTo(part * 12, size.height)
        ..moveTo(part * 13, 0)
        ..lineTo(part * 13, size.height)
        ..moveTo(part * 14, 0)
        ..lineTo(part * 14, size.height)
        ..moveTo(part * 15, 0)
        ..lineTo(part * 15, size.height)
        ..moveTo(part * 16, 0)
        ..lineTo(part * 16, size.height)
        ..moveTo(part * 17, 0)
        ..lineTo(part * 17, size.height)
        ..moveTo(part * 18, 0)
        ..lineTo(part * 18, size.height);
      // ..moveTo(0, size.height)
      // ..lineTo(size.width, size.height);
    }
  }

  //绘制底部的刻度栏子
  Widget getScaleLine() {
    List<Widget> list = [];
    if (_dotNum == 600) {
      for (var i = 1; i < 6; i++) {
        if (i % 2 != 0) {
          list.add(Expanded(
            child: Text(
              '${i * 100}',
              textAlign: TextAlign.center,
              style: const TextStyle(color: Color(0xFF999999), fontSize: 12),
            ),
          ));
        }
      }
    } else {
      for (var i = 1; i < 18; i++) {
        if (i % 2 != 0) {
          list.add(Expanded(
            child: Text(
              '${i * 100}',
              textAlign: TextAlign.center,
              style: const TextStyle(color: Color(0xFF999999), fontSize: 12),
            ),
          ));
        }
      }
    }
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: list,
    );
  }

  //绘制折线图
  Widget getLineChartView(
      List<DataListEntity> list,
      int position,
      Color lineColor,
      double maxX,
      double minX,
      double maxY,
      double minY,
      double maxWidth) {
    lineChartWidth = maxWidth;
    return LineChart(
      LineChartData(
        gridData: FlGridData(show: false),
        lineTouchData: LineTouchData(
            enabled: true,
            touchTooltipData: LineTouchTooltipData(
                //tooltipBgColor: Colors.blueAccent,
                tooltipPadding: EdgeInsets.zero,
                maxContentWidth: 1000,
                fitInsideVertically: true,
                fitInsideHorizontally: true,
                getTooltipItems: (List<LineBarSpot> touchedBarSpots) {
                  return touchedBarSpots.map((barSpot) {
                    final flSpot = barSpot;
                    return LineTooltipItem(
                      formatDate(
                          list[position].dataList[flSpot.x.toInt()].dateTime!,
                          [yyyy, '-', mm, '-', dd, ' ', HH, ':', nn, ':', ss]),
                      const TextStyle(
                        color: Colors.white,
                      ),
                      children: [
                        TextSpan(
                          text: '  ${flSpot.y.toString()}',
                          style: const TextStyle(
                            color: Colors.red,
                            fontWeight: FontWeight.normal,
                          ),
                        ),
                      ],
                    );
                  }).toList();
                })),
        titlesData: FlTitlesData(show: false),
        maxX: maxX,
        minX: minX,
        maxY: maxY,
        minY: minY,
        clipData: FlClipData.all(),
        borderData: FlBorderData(
          show: false,
        ),
        lineBarsData: [
          //? 绿线的配置
          LineChartBarData(
            //dashArray: [5, 10],
            //isStepLineChart: true,
            //? 取样点
            spots: list[position].flList,
            //? 是否是曲线
            isCurved: false,
            // curveSmoothness: 0,
            color: lineColor,
            //? 线的宽度
            barWidth: 1,
            //? 线头是否是圆形
            isStrokeCapRound: true,
            //? 是否显示数据点
            dotData: FlDotData(
              show: false,
            ),

            //? 是否显示线上区域
            // aboveBarData: BarAreaData(
            //   show: true,
            //   color: Color(0x444af699),
            // ),
          )
        ],
      ),
    );
  }

  //选择的模拟量弹框
  void _showDialog(int itemType) {
    int selectIndex = 0;
    Get.bottomSheet(
        SafeArea(
          child: SizedBox(
            //color: Colors.white,
            height: 240,
            child: Column(
              children: [
                Row(
                  children: [
                    TextButton(
                        onPressed: () {
                          Get.back();
                        },
                        child: const Text(
                          '取消',
                          style: TextStyle(color: Colors.blue, fontSize: 16),
                        )),
                    const Expanded(
                        child: Text(
                      '请选择',
                      style: TextStyle(fontSize: 16),
                      textAlign: TextAlign.center,
                    )),
                    TextButton(
                        onPressed: () {
                          setState(() {
                            switch (itemType) {
                              case 0:
                                if (selectIndex != _selectFirstItem) {
                                  _firstName = _effectiveList[selectIndex];
                                  _selectFirstItem = selectIndex;
                                  switchFillDataList(
                                    _firstItemList,
                                    _selectFirstItem,
                                    _deviceEntity!.itemType == 0
                                        ? dataMap
                                        : totalDataHistoryMap,
                                  );
                                  setState(() {
                                    _firstName;
                                  });
                                }
                                break;
                              case 1:
                                if (selectIndex != _selectSecondItem) {
                                  _secondName = _effectiveList[selectIndex];
                                  _selectSecondItem = selectIndex;
                                  switchFillDataList(
                                    _secondItemList,
                                    _selectSecondItem,
                                    _deviceEntity!.itemType == 0
                                        ? dataMap
                                        : totalDataHistoryMap,
                                  );
                                  setState(() {
                                    _secondName;
                                  });
                                }
                                break;
                              case 2:
                                if (selectIndex != _selectThirdItem) {
                                  _thirdName =
                                      _switchEffectiveList[selectIndex];
                                  _selectThirdItem = selectIndex;
                                  switchFillDataList(
                                    _thridItemList,
                                    _selectThirdItem,
                                    _deviceEntity!.itemType == 0
                                        ? switchDataMap
                                        : totalDataSwitchHistoryMap,
                                  );
                                  setState(() {
                                    _thirdName;
                                  });
                                }
                                break;
                              case 3:
                                if (selectIndex != _selectFourItem) {
                                  _fourName = _switchEffectiveList[selectIndex];
                                  _selectFourItem = selectIndex;
                                  switchFillDataList(
                                    _fourItemList,
                                    _selectFourItem,
                                    _deviceEntity!.itemType == 0
                                        ? switchDataMap
                                        : totalDataSwitchHistoryMap,
                                  );
                                  setState(() {
                                    _fourName;
                                  });
                                }
                                break;
                            }
                          });
                          Get.back();
                        },
                        child: const Text(
                          '确定',
                          style: TextStyle(color: Colors.blue, fontSize: 16),
                        ))
                  ],
                ),
                Expanded(
                    child: CupertinoPicker(
                  itemExtent: 40,
                  onSelectedItemChanged: (index) {
                    selectIndex = index;
                  },
                  children: itemType == 0 || itemType == 1
                      ? _effectiveList.map((data) {
                          return Center(
                            child: Text(data),
                          );
                        }).toList()
                      : _switchEffectiveList.map((data) {
                          return Center(
                            child: Text(data),
                          );
                        }).toList(),
                ))
              ],
            ),
          ),
        ),
        backgroundColor: Colors.white,
        shape: const RoundedRectangleBorder(
            borderRadius: BorderRadius.vertical(top: Radius.circular(15))));
  }

  //查询历史数据
  queryHistoryData(String command) {
    log(command);
    EasyLoading.show(
        status: "加载中...",
        maskType: EasyLoadingMaskType.clear,
        dismissOnTap: true);
    BytesBuilder byteList = BytesBuilder();
    bool isDataHeader = false;
    SocketServerManage().writeData(command, (value) {
      //查询数据
      if (!isDataHeader && String.fromCharCodes(value, 0, 16).contains('que')) {
        isDataHeader = true;
      }
      if (isDataHeader) {
        byteList.add(value);
      }
      if (isDataHeader && String.fromCharCodes(value).contains('over')) {
        isDataHeader = false;
        List<DataEntity> listData = DataUtils.judgeDataType(byteList.toBytes());
        processHistoryData(listData);
        EasyLoading.dismiss();
      }
    });
  }

  //处理30分钟或历史数据
  processHistoryData(List<DataEntity> dataList) {
    log(dataList.length.toString());
    dataHistoryMap.clear();
    dataSwitchHistoryMap.clear();
    dataHistoryEntityList.clear();
    List<String> nameList = Get.find<UserController>().bit100List;
    List<String> switchNameList = Get.find<UserController>().bit140List;
    if (dataList.length < loadHistoryLength) {
      isMoreHistory = false;
    }
    dateTime = dataList[dataList.length - 2].dateTime ?? dateTime;
    if (_deviceEntity!.itemType == 2) {
      dataList = dataList.reversed.toList();
    } else {
      for (var i = 0; i < dataList.length; i++) {
        if (i != 0) {
          DateTime before = dataList[i - 1].dateTime!;
          DateTime after = dataList[i].dateTime!;
          if (after.isBefore(before)) {
            var list1 = dataList.sublist(0, i);
            var list2 = dataList.sublist(i, dataList.length - 1);
            dataList.clear();
            dataList.addAll(list2);
            dataList.addAll(list1);
            break;
          }
        }
      }
    }
    log(dataList.first.dateTime.toString() +
        '----' +
        dataList.last.dateTime.toString());
    dataList.forEach((element) {
      //log(element.dateTime.toString());
      List<int> list = [];
      list.addAll(element.bit14List!);
      list.addAll(element.bit7List!);
      Map map = {};
      Map switchMap = {};
      for (var i = 0; i < nameList.length; i++) {
        if (nameList[i] != 'NULL') {
          map[nameList[i]] = list[i];
        }
      }
      for (var i = 0; i < switchNameList.length; i++) {
        if (switchNameList[i] != 'NULL') {
          switchMap[switchNameList[i]] = element.switchList![i];
        }
      }
      if (_firstName.isEmpty) {
        setState(() {
          _firstName = map.keys.toList()[_selectFirstItem];
          _secondName = map.keys.toList()[_selectSecondItem];
          _thirdName = switchMap.keys.toList()[_selectThirdItem];
          _fourName = switchMap.keys.toList()[_selectFourItem];
        });
      }

      dataHistoryEntityList.add(element);
      dataHistoryMap.add(map);
      dataSwitchHistoryMap.add(switchMap);
    });
    totalDataHistoryMap.insertAll(0, dataHistoryMap);
    totalDataSwitchHistoryMap.insertAll(0, dataSwitchHistoryMap);
    if (isFirstLoadHistroy) {
      fillDataList(_firstItemList, _selectFirstItem, dataHistoryMap,
          dataHistoryEntityList);
      fillDataList(_secondItemList, _selectSecondItem, dataHistoryMap,
          dataHistoryEntityList);
      fillDataList(_thridItemList, _selectThirdItem, dataSwitchHistoryMap,
          dataHistoryEntityList);
      fillDataList(_fourItemList, _selectFourItem, dataSwitchHistoryMap,
          dataHistoryEntityList);
    } else {
      fillMoreHistoryDataList(_firstItemList, _selectFirstItem, dataHistoryMap,
          dataHistoryEntityList);
      fillMoreHistoryDataList(_secondItemList, _selectSecondItem,
          dataHistoryMap, dataHistoryEntityList);
      fillMoreHistoryDataList(_thridItemList, _selectThirdItem,
          dataSwitchHistoryMap, dataHistoryEntityList);
      fillMoreHistoryDataList(_fourItemList, _selectFourItem,
          dataSwitchHistoryMap, dataHistoryEntityList);
    }
    if (isFirstLoadHistroy) {
      isFirstLoadHistroy = false;
      Future.delayed(const Duration(milliseconds: 50), () {
        _scrollController.jumpTo(_scrollController.position.maxScrollExtent);
      });
    }
    Future.delayed(const Duration(milliseconds: 50), () {
      isLoadHistory = false;
      _scrollController.jumpTo(lineChartWidth * 5);
      EasyLoading.dismiss();
    });
  }

  //格式化时间
  String getNowFormatTime(DateTime now) {
    int year = now.year - 2021 << 26;
    int month = now.month << 22;
    int day = now.day << 17;
    int hour = now.hour << 12;
    int minute = now.minute << 6;
    int second = now.second;
    return (year | month | day | hour | minute | second).toString();
  }

  //选择模拟量填充数据
  fillDataList(List<DataListEntity> list, int selectItem, List<Map> mapList,
      List<DataEntity> dataList) {
    list.clear();
    for (var i = 0; i < mapList.length; i++) {
      if (i % _dotNum == 0) {
        if (i != 0) {
          list.last.flList.add(FlSpot(
              _dotNum,
              double.parse(
                  mapList[i].values.elementAt(selectItem).toString())));
          list.last.dataList.add(dataList[i]);
        }
        list.add(DataListEntity([], []));
      }
      list.last.flList.add(FlSpot(i % _dotNum,
          double.parse(mapList[i].values.elementAt(selectItem).toString())));
      list.last.dataList.add(dataList[i]);
    }
    setState(() {
      list;
    });
  }

  //切换模拟量填充数据
  switchFillDataList(
      List<DataListEntity> list, int selectItem, List<Map> mapList) {
    List<DataListEntity> dataEntityList = [];
    dataEntityList.addAll(list);
    list.clear();
    //log(totalDataHistoryEntityList.length.toString());
    //无需天充点
    int n = 0;
    if (mapList.length > _dotNum &&
        mapList.length % _dotNum != 0 &&
        _deviceEntity!.itemType == 2) {
      n = (_dotNum - (mapList.length % _dotNum)).toInt();
    }
    int l = 0;
    for (var i = 0; i < mapList.length + n; i++) {
      if (i % _dotNum == 0) {
        if (i != 0) {
          list.last.flList.add(FlSpot(
              _dotNum,
              double.parse(
                  mapList[i - n].values.elementAt(selectItem).toString())));
        }
        list.add(DataListEntity(dataEntityList[l].dataList, []));
        l++;
      }
      if (i < n) {
        continue;
      }
      list.last.flList.add(FlSpot(
          i % _dotNum,
          double.parse(
              mapList[i - n].values.elementAt(selectItem).toString())));
    }
    setState(() {
      list;
    });
  }

  //选择模拟量填充数据
  fillMoreHistoryDataList(List<DataListEntity> list, int selectItem,
      List<Map> mapList, List<DataEntity> dataList) {
    List<DataListEntity> newList = [];
    int l = 0;
    if (mapList.length % _dotNum != 0) {
      l = (_dotNum - (mapList.length % _dotNum)).toInt();
    }
    for (var i = 0; i < mapList.length + l; i++) {
      if (i % _dotNum == 0) {
        if (i != 0) {
          newList.last.flList.add(FlSpot(
              _dotNum,
              double.parse(
                  mapList[i - l].values.elementAt(selectItem).toString())));
          newList.last.dataList.add(dataList[i - l]);
        }
        newList.add(DataListEntity([], []));
      }
      if (i < l) {
        continue;
      }
      newList.last.flList.add(FlSpot(
          i % _dotNum,
          double.parse(
              mapList[i - l].values.elementAt(selectItem).toString())));
      newList.last.dataList.add(dataList[i - l]);
    }
    list.insertAll(0, newList);
    //log('list: ${list.length.toString()}');
    setState(() {
      list;
    });
  }
}
